home *** CD-ROM | disk | FTP | other *** search
- .xlist
- include stdlib.a
- includelib stdlib.lib
- .list
-
- cseg segment para public 'code'
- assume ds:nothing
-
- ;****************************************************************************
- ;
- ; PutInATBuffer-
- ;
- ; The following code sticks the scan code into the AT-class keyboard
- ; microcontroller chip and asks it to send the scan code back to us
- ; (through the hardware port).
- ;
- ; The AT keyboard controller:
- ;
- ; Data port is at I/O address 60h
- ; Status port is at I/O address 64h (read only)
- ; Command port is at I/O address 64h (write only)
- ;
- ; The controller responds to the following values sent to the command port:
- ;
- ; 20h - Read Keyboard Controller's Command Byte (KCCB) and send the data to
- ; the data port (I/O address 60h).
- ;
- ; 60h - Write KCCB. The next byte written to I/O address 60h is placed in
- ; the KCCB. The bits of the KCCB are defined as follows:
- ;
- ; bit 7- Reserved, should be a zero
- ; bit 6- IBM industrial computer mode.
- ; bit 5- IBM industrial computer mode.
- ; bit 4- Disable keyboard.
- ; bit 3- Inhibit override.
- ; bit 2- System flag
- ; bit 1- Reserved, should be a zero.
- ; bit 0- Enable output buffer full interrupt.
- ;
- ; AAh - Self test
- ; ABh - Interface test
- ; ACh - Diagnostic dump
- ; ADh - Disable keyboard
- ; AEh - Enable keyboard
- ; C0h - Read Keyboard Controller input port (equip installed)
- ; D0h - Read Keyboard Controller output port
- ; D1h - Write Keyboard Controller output port
- ; E0h - Read test inputs
- ; F0h-FFh - Pulse Output port.
- ;
- ; The keyboard controller output port is defined as follows:
- ;
- ; bit 7 - Keyboard data (output)
- ; bit 6 - Keyboard clock (output)
- ; bit 5 - Input buffer empty
- ; bit 4 - Output buffer full
- ; bit 3 - undefined
- ; bit 2 - undefined
- ; bit 1 - Gate A20
- ; bit 0 - System reset (0=reset)
- ;
- ; The keyboard controller input port is defined as follows:
- ;
- ; bit 7 - Keyboard inhibit switch (0=inhibited)
- ; bit 6 - Display switch (0=color, 1= mono)
- ; bit 5 - Manufacturing jumper
- ; bit 4 - System board RAM (0=disable 2nd 256K RAM on system board).
- ; bits 0-3 - undefined.
- ;
- ; The keyboard controller status port (64h) is defined as follows:
- ;
- ; bit 1- Set if input data (60h) not available.
- ; bit 0- Set if output port (60h) cannot accept data.
-
-
-
- PutInATBuffer proc near
- assume ds:nothing
- pushf
- push ax
- push bx
- push cx
- push dx
-
-
- mov dl, al ;Save char to output.
-
- ; Wait until the keyboard controller does not contain data before
- ; proceeding with shoving stuff down its throat.
-
- xor cx, cx
- WaitWhileFull: in al, 64h
- test al, 1
- loopnz WaitWhileFull
-
-
- ; First things first, let's mask the interrupt controller chip (8259) to
- ; tell it to ignore interrupts coming from the keyboard. However, turn the
- ; interrupts on so we properly process interrupts from other sources (this
- ; is especially important because we're going to wind up sending a false
- ; EOI to the interrupt controller inside the INT 9 BIOS routine).
-
- cli
- in al, 21h ;Get current mask
- push ax ;Save intr mask
- or al, 2 ;Mask keyboard interrupt
- out 21h, al
-
- ; Transmit the desired scan code to the keyboard controller. Call this
- ; byte the new keyboard controller command (we've turned off the keyboard,
- ; so this won't affect anything).
- ;
- ; The following code tells the keyboard controller to take the next byte
- ; sent to it and use this byte as the KCCB:
-
-
- call WaitToXmit
- mov al, 60h ;Write new KCCB command.
- out 64h, al
-
- ; Send the scan code as the new KCCB:
-
- call WaitToXmit
- mov al, dl
- out 60h, al
-
- ; The following code instructs the system to transmit the KCCB (i.e., the
- ; scan code) to the system:
-
- call WaitToXmit
- mov al, 20h ;"Send KCCB" command.
- out 64h, al
-
- xor cx, cx
- Wait4OutFull: in al, 64h
- test al, 1
- loopz Wait4OutFull
-
- ; Okay, Send a 45h back as the new KCCB to allow the normal keyboard to work
- ; properly.
-
- call WaitToXmit
- mov al, 60h
- out 64h, al
-
- call WaitToXmit
- mov al, 45h
- out 60h, al
-
- ; Okay, execute an INT 9 routine so the BIOS (or whoever) can read the key
- ; we just stuffed into the keyboard controller. Since we've masked INT 9
- ; at the interrupt controller, there will be no interrupt coming along from
- ; the key we shoved in the buffer.
-
- DoInt9: in al, 60h ;Prevents ints from some codes.
- int 9 ;Simulate hardware kbd int.
-
-
- ; Just to be safe, reenable the keyboard:
-
- call WaitToXmit
- mov al, 0aeh
- out 64h, al
-
- ; Okay, restore the interrupt mask for the keyboard in the 8259a.
-
- pop ax
- out 21h, al
-
- pop dx
- pop cx
- pop bx
- pop ax
- popf
- ret
- PutInATBuffer endp
-
-
-
- ; WaitToXmit- Wait until it's okay to send a command byte to the keyboard
- ; controller port.
-
- WaitToXmit proc near
- push cx
- push ax
- xor cx, cx
- TstCmdPortLp: in al, 64h
- test al, 2 ;Check cntrlr input buffer full flag.
- loopnz TstCmdPortLp
- pop ax
- pop cx
- ret
- WaitToXmit endp
-
-
-
- ;****************************************************************************
- ;
- ; PutInPS2Buffer- Like PutInATBuffer, it uses the keyboard controller chip
- ; to return the keycode. However, PS/2 compatible controllers
- ; have an actual command to return keycodes.
-
- PutInPS2Buffer proc near
- pushf
- push ax
- push bx
- push cx
- push dx
-
- mov dl, al ;Save char to output.
-
- ; Wait until the keyboard controller does not contain data before
- ; proceeding with shoving stuff down its throat.
-
- xor cx, cx
- WaitWhileFull: in al, 64h
- test al, 1
- loopnz WaitWhileFull
-
-
- ; The following code tells the keyboard controller to take the next byte
- ; sent to it and return it as a scan code.
-
-
- call WaitToXmit
- mov al, 0d2h ;Return scan code command.
- out 64h, al
-
- ; Send the scan code:
-
- call WaitToXmit
- mov al, dl
- out 60h, al
-
- pop dx
- pop cx
- pop bx
- pop ax
- popf
- ret
- PutInPS2Buffer endp
-
-
- ; Main program - Simulates some keystrokes to demo the above code.
-
- Main proc
-
- mov ax, cseg
- mov ds, ax
-
- print
- byte "Simulating keystrokes via Trace Flag",cr,lf
- byte "This program places 'DIR' in the keyboard buffer"
- byte cr,lf,0
-
- mov al, 20h ;"D" down scan code
- call PutInATBuffer
- mov al, 0a0h ;"D" up scan code
- call PutInATBuffer
-
- mov al, 17h ;"I" down scan code
- call PutInATBuffer
- mov al, 97h ;"I" up scan code
- call PutInATBuffer
-
- mov al, 13h ;"R" down scan code
- call PutInATBuffer
- mov al, 93h ;"R" up scan code
- call PutInATBuffer
-
- mov al, 1Ch ;Enter down scan code
- call PutInATBuffer
- mov al, 9Ch ;Enter up scan code
- call PutInATBuffer
-
-
-
- ExitPgm
- Main endp
-
-
- cseg ends
-
- sseg segment para stack 'stack'
- stk db 1024 dup ("stack ")
- sseg ends
-
- zzzzzzseg segment para public 'zzzzzz'
- LastBytes db 16 dup (?)
- zzzzzzseg ends
- end Main
-
-